package com.liuya.shiro;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.liuya.common.SecurityUtil;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;

/**
 * 身份验证过滤器，负责执行用户的身份验证
 * @Author 刘亚
 * @Date 2016/12/7
 */
public class AuthenticationFilter extends FormAuthenticationFilter {
    private String password = "password";
    private String username = "username";
    private String captchaId = "captchaId";
    private String captcha = "captcha";
    private boolean rememberMe = false;

    /**
     * 在对用户进行身份验证前先创建一个token，此token将是验证成功后系统其它处用于判断用户的依据。
     */
    protected org.apache.shiro.authc.AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
        String una = getUsername(request);
        String pwd = getPassword(request);
        String aid = getAuthenId(request);
        String pr = cleanParam(request);
        boolean rem = isRememberMe(request);
        String host = getHost(request);
        return new AuthenticationToken(una, pwd, rem, aid, pr, host);
    }

    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse rep = (HttpServletResponse) response;
        String str = req.getHeader("X-Requested-With");
        if (str != null && str.equalsIgnoreCase("XMLHttpRequest")) {
            rep.addHeader("loginStatus", "accessDenied");
            rep.sendError(403);
            return false;
        }
        return super.onAccessDenied(req, rep);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected boolean onLoginSuccess(org.apache.shiro.authc.AuthenticationToken token, Subject subject,
                                     ServletRequest request, ServletResponse response) throws Exception {
        Session session = subject.getSession();
        Map map = new HashMap();
        Collection coll = session.getAttributeKeys();
        Iterator iter = coll.iterator();
        Object attrName;
        while (iter.hasNext()) {
            attrName = iter.next();
            map.put(attrName, session.getAttribute(attrName));
        }
        session.stop();
        session = subject.getSession();
        iter = map.entrySet().iterator();
        Map.Entry entry;
        while (iter.hasNext()) {
            entry = (Map.Entry) iter.next();
            session.setAttribute(entry.getKey(), entry.getValue());
        }
        return super.onLoginSuccess(token, subject, request, response);
    }

    protected String getPassword(ServletRequest request) {
        HttpServletRequest req = (HttpServletRequest) request;
        String str = request.getParameter("password");
        return SecurityUtil.encryptMD5Hex(str);
    }

    protected String getUsername(ServletRequest request) {
        HttpServletRequest req = (HttpServletRequest) request;
        String str = request.getParameter("username");
        return str;
    }

    protected boolean isRememberMe(ServletRequest request) {
        HttpServletRequest req = (HttpServletRequest) request;
        String str = request.getParameter("rememberMe");
        if(str!=null && !str.equals(""))
            return Boolean.valueOf(str).booleanValue();
        return false;
    }

    protected String getAuthenId(ServletRequest request) {
        String str = WebUtils.getCleanParam(request, this.captchaId);
        if (str == null)
            str = ((HttpServletRequest) request).getSession().getId();
        return str;
    }

    protected String cleanParam(ServletRequest request) {
        return WebUtils.getCleanParam(request, this.captcha);
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() {
        return this.username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public boolean getRememberMe() {
        return this.rememberMe;
    }

    public void setRememberMe(boolean rememberMe) {
        this.rememberMe = rememberMe;
    }

    /**
     * 返回验证码
     * @return
     */
    public String getCaptchaId() {
        return this.captchaId;
    }

    /**
     * 设置验证码
     * @param captchaId
     */
    public void setCaptchaId(String captchaId) {
        this.captchaId = captchaId;
    }

    public String getCaptcha() {
        return this.captcha;
    }

    public void setCaptcha(String captcha) {
        this.captcha = captcha;
    }
}